<?php
/*******************************************************************
* Glype Proxy Script
*
* Copyright (c) 2008, http://www.glype.com/
*
* Permission to use this script is granted free of charge
* subject to the terms displayed at http://www.glype.com/downloads
* and in the LICENSE.txt document of the glype package.
*******************************************************************
* This file is the processor that takes incoming data and processes
* it, surprisingly enough. Works with various aspects of the script.
******************************************************************/

/*****************************************************************
* Initialise
******************************************************************/

require 'includes/init.php';

class Custom_Glype_Process
{


    static function execute($action)
    {
        /*****************************************************************
        * Switch - action depends on the action parameter
        ******************************************************************/


        //$action = isset($_GET['action']) ? $_GET['action'] : false;

        switch ( $action )
        {

           /*************************************************************
           * Update location - accept URL posted from index page or mini-form,
           * find options, convert to a 'proxified' URL and redirect there.
           **************************************************************/
           case 'update':

              // Valid input?
              if ( ! isset($_POST['u']) || ! ( $url = clean($_POST['u']) ) ) {
                 break;
              }

              // Check for a http protocol (no other protocols are supported)
              if ( ! preg_match('#^https?://#i', $url) ) {
                 $url = 'http://' . $url;
              }

              // Generate bitfield from new options
              $bitfield = 0;
              $i = 0;

              foreach ( $CONFIG['options'] as $name => $details ) {

                 // Ignore forced
                 if ( ! empty($details['force']) ) {
                    continue;
                 }

                 // Current bit
                 $bit = pow(2, $i);

                 // Set bitfield
                 if ( ! empty($_POST[$name]) ) {
                    setBit($bitfield, $bit);
                 }

                 // Increase index
                 ++$i;

              }

              // Save new bitfield in session
              $_SESSION['bitfield'] = $bitfield;

              // Save valid entry
              $_SESSION['no_hotlink'] = true;

              // Redirect to target
              redirect(proxifyURL($url, 'norefer'));

              break;


           /*************************************************************
           * Agree to our SSL warning.
           **************************************************************/
           case 'sslagree':

              // Flag our SSL warnedness
              $_SESSION['ssl_warned'] = true;

              // Return to previous page
              $redirectTo = isset($_SESSION['return']) ? $_SESSION['return'] : INDEX_PATH;

              // Clear session return value
              unset($_SESSION['return']);

              // Redirect
              redirect($redirectTo);

              break;


           /*****************************************************************
           * Accept authorization credentials - accept data from _POST (session
           * may be closed before the server challenged us for authentication)/
           * Store the POSTed credentials in the session and redirect back to
           * requested page. The script will then use the provided credentials to
           * try again.
           ******************************************************************/
           case 'authenticate':

              // Ensure we have a page to return to and a site to apply the credentials to
              if ( empty($_POST['return']) || empty($_POST['site']) ) {
                 break;
              }

              // Determine username/password
              $credentials = ( ! empty($_POST['user']) ? clean($_POST['user']) : '' )
                             . ':' .
                             ( ! empty($_POST['pass']) ? clean($_POST['pass']) : '' );

              // Save in session
              $_SESSION['authenticate'][clean($_POST['site'])] = $credentials;

              // Redirect back to target page
              redirect(clean($_POST['return']));

              break;

           /*****************************************************************
           * Clear all proxified cookies
           ******************************************************************/
           case 'clear-cookies':

              // Where we do redirect back?
              $redirect = isset($_GET['return']) ? $_GET['return'] : INDEX_PATH;

              // Server side cookies?
              if ( $CONFIG['cookies_on_server'] ) {

                 // Look for cookie file and check writable
                 if ( is_writable($file = $CONFIG['cookies_folder'] . session_id()) ) {

                    // Delete it
                    unlink($file);

                 }

              } else {

                 // Client side cookies so check cookies exist
                 if ( empty($_COOKIE[COOKIE_PREFIX]) || ! is_array($_COOKIE[COOKIE_PREFIX]) ) {
                    redirect($redirect);
                 }

                 // Recursive function to delete multi-dimensional cookie arrays
                 function deleteAllCookies($array, $prefix='') {

                    // Loop through each level
                    foreach ( $array as $name => $value ) {

                       $thisLevel = $prefix . '[' . $name . ']';

                       if ( is_array($value) ) {

                          // If another array, recurse
                          deleteAllCookies($value, $thisLevel);

                       } else {

                          // Do the deletion
                          setcookie($thisLevel, '', $_SERVER['REQUEST_TIME']-3600, '/', '');

                       }

                    }

                 }

                 deleteAllCookies($_COOKIE[COOKIE_PREFIX], COOKIE_PREFIX);

              }

              // And redirect
              redirect($redirect);

              break;


              /*****************************************************************
              * Delete individual proxified cookies
              ******************************************************************/
              case 'cookies':

                 // Check we have some to delete
                 if ( empty($_POST['delete']) || ! is_array($_POST['delete']) ) {
                    redirect('cookies.php');
                 }

                 // Go through all submitted cookies and delete them.
                 if ( $CONFIG['cookies_on_server'] ) {

                    // Server-side storage. Look for cookie file.
                    if ( file_exists($cookieFile = $CONFIG['cookies_folder'] . session_id()) && ( $file = file($cookieFile) ) ) {

                       // Loop through lines, looking for cookies to delete
                       foreach ( $file as $id => $line ) {

                          // Ignore comment lines
                          if ( ! isset($line[0]) || $line[0] == '#' ) {
                             continue;
                          }

                          // Split by tab
                          $details = explode('	', $line);

                          // Check valid split, expecting 7 items
                          if ( count($details) != 7 ) {
                             continue;
                          }

                          // Create string formatted in same way as our input
                          $cookie = $details[0] . '|' . $details[2] . '|' . $details[5];

                          // Are we deleting this?
                          if ( in_array($cookie, $_POST['delete']) ) {
                             unset($file[$id]);
                          }

                       }

                       // Put file back together
                       file_put_contents($cookieFile, $file);

                    }

                 } else {

                    // Client-side cookies

                    // Generate an expiry time in the past
                    $expires = time() - 3600;

                    // Client-side cookies - split by | to get cookie details
                    foreach ( $_POST['delete'] as $cookie ) {

                       $details = explode('|', $cookie, 3);

                       // Check for successful split
                       if ( ! isset($details[2]) ) {
                          continue;
                       }

                       // Extract parts
                       list($domain, $path, $name) = $details;

                       // Generate an encoded/unencoded cookie name, depending on settings
                       if ( $CONFIG['encode_cookies'] ) {
                          $name = COOKIE_PREFIX . '[' . urlencode(base64_encode($domain . ' ' . $path . ' ' . urlencode($name))) . ']';
                       } else {
                          $name = COOKIE_PREFIX . '[' . $domain . '][' . $path . '][' . $name . ']';
                       }

                       // And unset
                       setcookie($name, '', $expires, '/');

                    }

                 }

                 // Redirect back to cookie page
                 redirect('cookies.php');

                 break;


              /*****************************************************************
              * Edit virtual browser
              ******************************************************************/
              case 'edit-browser':

                 // Prepare submitted information
                 $browser['user_agent'] = isset($_POST['user-agent'])    ? clean($_POST['user-agent']) : '';
                 $browser['referrer']   = empty($_POST['real-referrer']) ? 'custom'                    : 'real';

                 if ( $browser['referrer'] == 'custom' ) {
                    $browser['referrer'] = isset($_POST['custom-referrer']) ? clean($_POST['custom-referrer']) : '';
                 }

                 // Only save tunnel information if all was submitted
                 if ( empty($_POST['tunnel']) || empty($_POST['tunnel-port']) || empty($_POST['tunnel-type']) ) {

                    $browser['tunnel'] = $browser['tunnel_port'] = $browser['tunnel_type'] = '';

                 } else {
                    $browser['tunnel']      = clean($_POST['tunnel']);
                    $browser['tunnel_port'] = clean($_POST['tunnel-port']);
                    $browser['tunnel_type'] = clean($_POST['tunnel-type']);
                 }

                 // Save in session
                 $_SESSION['custom_browser'] = $browser;

                 // Anywhere to go back to?
                 if ( isset($_POST['return']) ) {
                    redirect($_POST['return']);
                 }

                 redirect('edit-browser.php');

                 break;


              /*****************************************************************
              * Receive results of javascript capability testing
              ******************************************************************/
              case 'jstest':

                 // Don't cache ajax
                 sendNoCache();

                 // Save in session
                 $_SESSION['js_flags'] = array();

                 // Valid parsing flags
                 $valid = array('ajax', 'watch', 'setters');

                 // Grab results from query string
                 foreach ( $_GET as $name => $value ) {

                    // If a valid item, save
                    if ( in_array($name, $valid) ) {
                       $_SESSION['js_flags'][$name] = true;
                    }

                 }

                 // Done
                 echo 'ok';
                 exit;


        }


        /*****************************************************************
        * Still here? Then action = unrecognised, or invalid input. Redirect
        * to index page.
        ******************************************************************/

        redirect();
    }
}